/**
 * Created by Qingger Corp.
 * User: jsspf
 * Date: 2017/12/16
 * Time: 22:41
 */

/**
 * TypeScript中有些独特的概念可以在类型层面上描述JavaScript对象的模型。
 * 这其中尤其独特的一个例子是“声明合并”的概念。 理解了这个概念，将有助于操作现有的JavaScript代码。
 * 同时，也会有助于理解更多高级抽象的概念。
 *
 * “声明合并”是指编译器将针对同一个名字的两个独立声明合并为单一声明。
 * 合并后的声明同时拥有原先两个声明的特性。 任何数量的声明都可被合并；不局限于两个声明。
 */


// 1.接口的合并
interface Box {
    height : number;
    width : number;
}

interface Box {
    scale : number;
}


let box : Box = {
    height : 100,
    width : 10,
    scale : 200
};


// 2. 命名空间的合并
namespace Animals {
    export class Zebra {

    }
}

namespace Animals {
    export interface Legged {
        numberOfLegs : number;
    }

    export class Dog {

    }
}

let ad = new Animals.Dog();

// 3.合并命名空间和类/函数
// 你在JavaScript里，创建一个函数稍后扩展它增加一些属性也是很常见的。 TypeScript使用声明合并来达到这个目的并保证类型安全。
declare function buildLabel(name:string) : string;

namespace buildLabel {
   export let suffix = "";
   export declare function newFunc(i:number) : void;
}

buildLabel("abc");
buildLabel.newFunc(123);


// 4.枚举也可以与命名空间合并
enum Color {
    red = 1,
    green = 2,
    blue = 4
}

namespace Color {
   export function mixColor(colorName : string) {
       if (colorName == "yellow") {
           return Color.red + Color.green;
       }
       else if (colorName == "white") {
           return Color.red + Color.green + Color.blue;
       }
       else if (colorName == "magenta") {
           return Color.red + Color.blue;
       }
       else if (colorName == "cyan") {
           return Color.green + Color.blue;
       }
   }
}

// 5. 目前，类不能与其它类或变量合并。
// 也就是说不能定义两个相同名称的class ,如果需要实现类的合并，可以参考混入(mixins)


// 函数类型的接口, 实现1)可以直接使用函数，2)可以当类使用, 3) 可以
interface AxInstance {
    (config:object) : void;

    new (config:object) : void;

    request(config:object) : void;
}

interface Axstaic extends AxInstance {
    create(config:object) : void;
}

declare var axos : Axstaic;


